package com.jfsnpm.controller;


import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.Process;
import org.snaker.engine.entity.Order;
import org.snaker.engine.entity.Task;
import org.snaker.engine.model.TaskModel.TaskType;
import org.snaker.jfinal.plugin.SnakerPlugin;

import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfsnpm.action.PmProcess;
import com.jfsnpm.action.PmUser;
import com.jfsnpm.authority.AuthorityCheck;
import com.jfsnpm.common.AppSql;
import com.jfsnpm.common.AppTool;
import com.jfsnpm.common.FlowTool;
import com.jfsnpm.common.MenuTree4Auth;
import com.jfsnpm.plugin.bjui.Bjui;
import com.jfsnpm.plugin.bjui.BjuiRender;

/**
 *流程相关
 * @author 天为之殇
 *
 */
public class FlowController extends Controller {
	/**
	 * 流程列表显示
	 */
	public void process(){
		Bjui.BjuiPageByTableName("wf_process", "name,display_Name", "version asc", this);
	}
	public void process_getuser(){
		String processid = getPara("processid","");
		setAttr("menulist", PmProcess.getAllOrgWithAuth(processid));
		setAttr("processid", processid);
	}
	public void process_user_save(){
		String menus = getPara("menus");
		String processid = getPara("processid");
		MenuTree4Auth tree = AppTool.json2MenuTree4Auth(menus);
		if(tree.saveTree4Auth4Process(processid)){
			render(BjuiRender.success("保存成功！", false));
		}else{
			render(BjuiRender.error("保存失败！", false));
		}
	}
	/**
	 * 流程启动
	 */
	@Before(Tx.class)
	public void process_start(){
		String userid = getSessionAttr("userid");
		String processid = getPara("processid");
		//权限判断
		if(!AuthorityCheck.getProcessAuthoriy(userid, processid)){render(BjuiRender.code(401));return;}
		//启动流程-获得order
		Map<String, Object> args = new HashMap<String, Object>();
		// TODO:获取执行者的map写入
		args.put("user", userid);
		args = FlowTool.setFlowUsers(args);
		args.put("notice_time", new Date(System.currentTimeMillis()+120000));
		Order order = SnakerPlugin.getEngine().startInstanceById(processid, userid , args);
		Process process = SnakerPlugin.getEngine().process().getProcessById(processid);
		String formpath=process.getInstanceUrl();
		if(StringUtils.isBlank(formpath)){
			formpath = process.getName();
		}
		//order扩展表写入数据
		Db.save("pm_ext_wf_order", new Record().set("orderid", order.getId()));
		//相关表单写入数据
		Db.save("form_"+formpath, new Record().set("id", order.getId())
				.set("pm_creator",getSessionAttr("username"))
				.set("pm_creator_dept", PmUser.getUserDeptById(userid))
				);
		
		List<Task> tasks = SnakerPlugin.getEngine().query().getActiveTasks(new QueryFilter().setOrderId(order.getId()));
		String taskid = null;
		for(Task task:tasks){
			if(StringUtils.startsWithAny(userid, SnakerPlugin.getEngine().query().getTaskActorsByTaskId(task.getId()))){
				taskid = task.getId();
				break;
			}
		}
		if(StringUtils.isBlank(taskid)){
			//仅提示启动成功
			//renderText("流程启动成功，流程当前没有您的相关任务！");
			render("process_start_success.html");
			//render(BjuiRender.success("流程启动成功，流程当前没有您的相关任务！").divid("mytodoTopTen"));
			return;
		}
		Bjui.BjuiReloadUrl(this, "../Flow/task_view?taskid="+taskid, "");
		//render(BjuiRender.success("流程启动成功！", false).forward("task_view?taskid="+taskid).divid("mytodoTopTen"));
	}
	/**
	 * 任务显示
	 */
	public void task_view(){
		String userid = getSessionAttr("userid");
		String taskid = getPara("taskid");
		FlowTool.flowview(userid, taskid, this);
	}
	/**
	 * 获取任务的表单
	 */
	public void task_viewForm(){
		String userid = getSessionAttr("userid");
		String taskid = getPara("taskid");
		FlowTool.flowviewform(userid, taskid, this);
	}
	/**
	 * 任务 执行 转发 驳回 操作
	 */
	public void task_exec(){
		String userid = getSessionAttr("userid");
		String taskid = getPara("taskid");
		Integer type = getParaToInt("type");
		String typename = getPara("typename");
		String typedesc = getPara("typedesc");
		if(StringUtils.isBlank(userid)||StringUtils.isBlank(taskid)||type==null
				||StringUtils.isBlank(typename)||StringUtils.isBlank(typedesc)){render(BjuiRender.code(801));return;}
		Map<String,Object> args = new HashMap<String, Object>();
		args.put("flow_operate_mark", typedesc);
		args.put("flow_operate", typename);
		switch (type) {
		case 1://流转
			SnakerPlugin.getEngine().executeTask(taskid, userid,args);
			render(BjuiRender.success("流传成功！").divid("mytodoTopTen"));
			return;
		case 0://任务转发
			String actors = getPara("actors");
			SnakerPlugin.getEngine().task().createNewTask(taskid, TaskType.Major.ordinal(),actors.split(","));
			SnakerPlugin.getEngine().task().complete(taskid, userid, args);
			render(BjuiRender.success("转发成功！").divid("mytodoTopTen"));
			break;
		case -1://驳回
			SnakerPlugin.getEngine().executeAndJumpTask(taskid, userid, args, null);
			render(BjuiRender.success("驳回成功！").divid("mytodoTopTen"));
			return;
		default:
			render(BjuiRender.code(801));
			return;
		}
	}
	// TODO:抄送任务建立
	/**
	 * 流程实例列表
	 */
	public void order_list(){
		Bjui.BjuiPage(AppSql.getsql("Flow.orderList"), "wf_hist_order.order_State,wf_process.display_Name,pm_ext_wf_order.orderTitle",
				"wf_hist_order.create_Time desc", this);
	}
	/**
	 * 流程实例查看
	 */
	public void order_view(){
		String userid = getSessionAttr("userid");
		String orderid = getPara("orderid");
		FlowTool.orderview(userid, orderid, this);
	}
	/**
	 * 获取流程实例表单-只读
	 */
	public void order_viewForm(){
		String userid = getSessionAttr("userid");
		String orderid = getPara("orderid");
		FlowTool.flowviewformbyorderid(userid, orderid, this);
	}
	/**
	 * 级联删除流程实例
	 */
	@Before(Tx.class)
	public void order_delete(){
		String orderid = getPara("orderid");
		if(StringUtils.isBlank(orderid)){render(BjuiRender.code(801));return;}
		Process process = SnakerPlugin.getEngine().process().getProcessById(
				SnakerPlugin.getEngine().query().getOrder(orderid).getProcessId());
		String formpath=process.getInstanceUrl();
		if(StringUtils.isBlank(formpath)){
			formpath = process.getName();
		}
		
		SnakerPlugin.getEngine().order().cascadeRemove(orderid);
		//TODO:暂时用order id作为表单主键，后续需改为从Variable字段获取
		if(Db.deleteById("pm_ext_wf_order", "orderid", orderid)&&
				Db.deleteById("form_"+formpath, "id", orderid)){
			render(BjuiRender.success("删除流程实例成功！").divid("mytodoTopTen"));
		}else{
			render(BjuiRender.error("删除失败！"));
		}
		
	}
	/**
	 * 流程实例 强制终止
	 */
	public void order_terminate(){
		String orderid = getPara("orderid");
		String userid = getSessionAttr("userid");
		if(StringUtils.isBlank(orderid)){render(BjuiRender.code(801));return;}
		SnakerPlugin.getEngine().order().terminate(orderid, userid);
		render(BjuiRender.success("强制终止流程实例成功！").divid("mytodoTopTen"));
	}
	/**
	 * 更新任务的表单 
	 * 主要参数：
	 * 表名=__formpath 
	 * 主键=__id 
	 * 实例标题列名= __ordertitlecolname
	 * 写入流程MAP列名s=__argscolname(以,间隔)
	 */
	public void form_save(){
		String formpath = getPara("__formpath");
		String formid = getPara("__id");
		//流程实例Title
		String ordertitlecolname = getPara("__ordertitlecolname");
		String orderid = getPara("__orderid");
		if(StringUtils.isNotBlank(ordertitlecolname)&&StringUtils.isNotBlank(orderid)){
			String ordertitle = getPara(ordertitlecolname);
			if(StringUtils.isNotBlank(ordertitle)){
				Db.update(AppSql.getsql("Flow.orderextUpdate"),ordertitle,orderid);
			}
		}
		//流程全局变量args
		if(StringUtils.isNotBlank(orderid)){
			String argscolname = getPara("__argscolname");
			String[] argscolnames = StringUtils.split(argscolname, ',');
			Map<String,Object> args = new HashMap<String, Object>();
			for(String argname:argscolnames){
				String arg = getPara(argname);
				if(StringUtils.isNotBlank(arg)){
					args.put(argname, arg);
				}
			}
			SnakerPlugin.getEngine().order().addVariable(orderid, args);
		}
		//更新表单
		if(StringUtils.isBlank(formpath) || StringUtils.isBlank(formid)){render(BjuiRender.code(801));return;}
		Record formdata = Db.findById("form_"+formpath, formid);
		Map<String, String[]> paramap = getParaMap();
		Set<String> key = paramap.keySet();
        for (Iterator<String> it = key.iterator(); it.hasNext();) {
            String paraname = it.next();
            if(StringUtils.startsWith(paraname, "__")) continue;
            if(StringUtils.isBlank(getPara(paraname))) continue;
            if(StringUtils.contains(paraname, "*")) continue;
            formdata.set(paraname, getPara(paraname));
        }
		if(Db.update("form_"+formpath, formdata)){
			if(Bjui.updateTable("form_"+formpath+"_detail", this)){
				render(BjuiRender.success("保存成功！", false));
			}else{
				render(BjuiRender.error("保存失败！"));
			}
		}else{
			render(BjuiRender.error("保存失败！"));
		}
	}
	/**
	 * 获取转发用的用户列表
	 */
	public void get_user(){
		String id = getPara("ids","__actorsid");
		String name = getPara("names","__actorsname");
		setAttr("ids", id);
		setAttr("names", name);
		Bjui.BjuiPage("select * from pm_user where status <> '禁用'", "no,name", this);
		
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
